package ualrcdg.client;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;

import javax.xml.transform.TransformerException;

import org.w3c.dom.Document;
import org.xml.sax.SAXException;

import ualrcdg.shared.CDGXMLHelper;
import ualrcdg.shared.XMLHelper;
import ualrcdg.shared.exceptions.CDGException;

/**
 * This class provides a way for the client application to communicate with the server using sockets
 */
public class Communicator {

	private final Socket socket;
	private final InputStream in;
	private final OutputStream out;
	private final static String hostname = "127.0.0.1";
	private final static int portnumber = 3333;

	/**
	 * This constructor provides a communicator with a socket.
	 */
	public Communicator() throws CDGException
	{
		
		try
		{
			this.socket = new Socket(Communicator.hostname, Communicator.portnumber);
			in = socket.getInputStream();
		}
		catch( IOException e )
		{
			throw new CDGException( "Error in Communicator: unable to fetch input stream." , e );
		}
		try
		{
			out = socket.getOutputStream( );
		}
		catch( IOException e )
		{
			throw new CDGException( "Error in Communicator: unable to fetch input stream." , e );
		}
		
		System.out.println( "New Communicator started with socket = " + socket.toString( ) );
	}

	/**
	 * This method sends a DOM document object to a socket as a request returns a response
	 * @param request sent to the server
	 * @return response from the server
	 */
	public Document run (Document request)
	{
		try
		{
			XMLHelper.writeDocumentToStream(request, out);
		}
		catch (TransformerException e) {
			
			System.out.println( "Error in Communicator: unable to write request document to stream." );
			e.printStackTrace();
			closeSocket( );
			return null;
		}
		
		Document response = null;

		try
		{
			response = CDGXMLHelper.parseDocumentFromStream( in );
		}
		catch( IOException e )
		{
			System.out.println( "Error in Communicator: unable to parse response document from stream."  );
			e.printStackTrace();
			closeSocket( );
			return null;
		}
		catch( SAXException e)
		{
			System.out.println( "Error in Communicator: unable to parse request document from stream."  );
			e.printStackTrace();
			closeSocket( );
			return null;
		}
		//TODO check id of response to match with request
		return response;
	}
	/**
	 * This method closes the socket
	 */
	private void closeSocket( )
	{
		try
		{
			socket.close( );
		}
		catch( IOException e )
		{
			System.out.println( "Error in Communicator: unable to close socket ( " + socket.toString( ) + " )" );
		}

	}
}
